跳到主要内容

Nginx学习

前置准备

所谓的 Web 服务器其实就是 HTTP 服务器(一般情况)

904696074e077934e601f175913f42fd_720w.jpg

它通常运行在服务器之上,绑定服务器的 IP 地址并监听某一个 TCP 端口来接收并处理 HTTP 请求

常见的 Web 服务器

1、Apache 服务器 Apache 服务器不要和 Apache 基金会弄混,Apache HTTP Server Project 是Apache软件基金会下的一个项目,优势主要在于源代码开放、有一支开放的开发队伍、支持跨平台应用以及其可移植性等。虽然 Apache 的模块支持非常丰富,但在速度和性能上不及其他轻量级 WEB 服务器,且所消耗的内存也比其他 WEB 服务器要高,所以用的人越来越少了。截止到 2020 年还是有很多人用这玩意的,具体看这里 October 2020 Web Server Survey

image.png

2、Nginx 服务器:这个下面会讲

3、Tomcat 服务器 与 Apache HTTP Server 相比,Tomcat 能够动态的生成资源并返回到客户端。Apache HTTP Server 和 Nginx 都能够将某一个文本文件的内容通过 HTTP 协议返回到客户端,但是这个文本文件的内容是固定的,也就是说无论何时、任何人访问它得到的内容都是完全相同的,这样的资源称之为静态资源。Apache HTTP Server 和 Nginx 本身不支持生成动态页面,但它们可以通过其他模块来支持(例如通过 Shell、PHP、Python 脚本程序来动态生成内容)。

虽然 Tomcat 也可以认为是 HTTP 服务器,但通常它会和 Nginx 一起使用(因为它的高并发和静态文件的处理太弱鸡了):

  • 动静态资源分离:运用 Nginx 的反向代理功能分发请求:所有动态资源的请求交给 Tomcat,而静态资源的请求(例如图片、视频、CSS、JavaScript文件等)则直接由 Nginx 返回到浏览器,这样能大大减轻 Tomcat 的压力。
  • 负载均衡,当业务压力增大时,可能一个 Tomcat 的实例不足以处理,那么这时可以启动多个 Tomcat 实例进行水平扩展,而 Nginx 的负载均衡功能可以把请求通过算法分发到各个不同的实例进行处理

4、Lighttpd 服务器 Lighttpd 是提供一个专门针对高性能网站,安全、快速、兼容性好并且灵活的 WEB Server 环境,它具有内存开销低、CPU占有率低、效能好,以及模块丰富等特点。支持 FastCGI、CGI、Auth、输出压缩、URL重写及 Alias 等重要功能,属于轻量级 WEB 服务器。(不过老实说,这个好像有点过时了,网上基本上很难找到相关的资料)

5、Microsoft IIS 服务器 在学习 WinServer 时使用过,这个是微软服务器版自带的,我觉得更大优势在于它能够使用 GUI 来控制,但是 IIS 主要支持 ASP 语言环境(.Net),且他是集成于 Windows 操作系统中的组件,要想合法使用 IIS 就要购买正版 Windows 操作系统,所以跨平台方面不是很友好,不过很多老的项目用的还是这个,早期很多使用 .NET 开发的政府部门的网站之类的

什么是 Nginx ?

先来了解下什么是正向代理,什么是反向代理?

  • 正向代理:就是正常的通过代理服务器(例如访问谷歌需要代理)访问远程服务器

  • 反向代理:客户端不需要任何配置就可以访问,只需把请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,再返回数据给客户端 作用是:暴露的是代理服务器地址,隐藏了真实服务器 IP 地址(或者把某个端口绑定到子域名上)

Nginx 的几个优势

  • Nginx 配置文件比较简单(基于代码块的结构)
  • Nginx 支持网站的 URL 地址重写(例如网站需要域名更换时),还能根据 URL 的特点,进行一个请求转发(判断这个请求是来自于移动端还是客户端)
  • Nginx 支持高可用配置,可以部署一个集群(防止单点崩溃)
  • Nginx 支持 gzip 压缩功能,像一些很大的静态资源(例如图片),可以压缩后再发送
  • Nginx 还支持热部署,可以在不停止 Nginx 的情况下更新代码

Nginx 的功能

  1. 静态站点
  2. 反向代理
  3. 负载均衡
  4. 缓存服务
  5. URL 重写
  6. 动静态请求分离
  7. HTTPS
  8. LUA 开发
  9. Nginx 安全
  10. Nginx 调优

Nginx 主要的应用场景

1、HTTP 服务器:Nginx 可以独立提供 HTTP 服务,所以可以用来做网页静态服务器 2、虚拟主机:可以实现在一台服务器模拟出多个网站,实际上就是配置多个服务(如下所示,一个 Server 表示一个服务)

server {
listen 443; # 监听的端口
server_name alsritter.icu; # 监听的域名
# ...
}


server {
listen 80;
server_name alsritter.icu;
# ...
}


server {
listen 80;
server_name code.alsritter.icu;
# ...
}

3、反向代理、负载均衡:当网站访问量达到一定程度后,单台服务器不能满足用户的请求时,需要多台服务器集群可以使用 Nginx 做反向代理。并且多台服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置

a3u4oD.png

配置环境

参考资料 傅毅--nginx服务器详细安装过程(使用yum 和 源码包两种安装方式,并说明其区别)

安装 nginx 有两种方式,一种是 在线安装,另一种是下载源码之后 自行编译生成可执行文件(所以需要 gc++ 环境)

下载源码编译的好处是:因为是在自己的系统上编译的,更符合自己系统的性能,也就是说在自己的系统上执行 nginx 服务性能效率更好。

# 因为 nginx 也是c语言开发的,所以需要 gc++ 环境
# 这里使用 build-essential 集成了这个环境
sudo apt-get install build-essential

下面只介绍在线安装的方式(编译的好麻烦)

换个源:打开sources.list文件

/etc/apt/sources.list

编辑 sources.list 文件, 在文件最前面添加阿里云镜像源:

#  阿里源
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse

刷新列表:

sudo apt-get update
sudo apt-get upgrade

安装环境:

# 更新包
sudo apt-get update
# 下载安装nginx
sudo apt-get install nginx

补充: service 指令是用来启动或停止系统服务,可以通过 service --status-all 来查看有哪些

# 启动
sudo service nginx start
# 启动之后访问 http://localhost/ 就能看到欢迎页了
# 但是如果是 WSL 则需要修改配置文件,因为 Windows 的 1000 以下的端口需要权限

# 停止
sudo service nginx stop

# 重启
sudo service nginx restart

因为使用的 WSL 所以还需要更改默认的端口

server{
listen 8091 default_server; # 修改监听端口
listen [::]:8091 default_server; # 修改监听端口
}

卸载 Nginx

# 先检查端口是否被占用
lsof -i :80
# 先关闭 nginx
sudo service nginx stop

dpkg --get-selections|grep nginx

sudo apt-get --purge remove nginx
sudo apt-get --purge remove nginx-common
sudo apt-get --purge remove nginx-core

# 再检查
dpkg --get-selections|grep nginx

which nginx # 不在显示nginx

Nginx 中的进程

ps -ef | grep -i "nginx" # 查找 nginx 服务

可以发现 Nginx 根据 CPU 的核心数自动创建了多个进程(一个主进程和多个工作进程)

root        41     9  0 14:54 ?        00:00:00 nginx: master process nginx
www-data 42 41 0 14:54 ? 00:00:00 nginx: worker process
www-data 43 41 0 14:54 ? 00:00:00 nginx: worker process
www-data 44 41 0 14:54 ? 00:00:00 nginx: worker process
www-data 45 41 0 14:54 ? 00:00:00 nginx: worker process
www-data 46 41 0 14:54 ? 00:00:00 nginx: worker process
www-data 47 41 0 14:54 ? 00:00:00 nginx: worker process
www-data 48 41 0 14:54 ? 00:00:00 nginx: worker process
www-data 49 41 0 14:54 ? 00:00:00 nginx: worker process

其中的 master 主进程是 不处理请求 的,而是分配请求发给 worker 进程,主进程负责重启、热加载、热部署等等,master 根据配置文件中的 worker_processes 定义启动时创建的工作进程数量

当 worker 运行后,master 就处于一个等待状态,等待用户的请求来临,或者系统信号(就是 -s 发送的信号),所以系统管理员可以发送 kill 指令或 nginx -s 信号的方式操作 nginx

Nginx 命令行操作

nginx # 初次启动可以直接输入 nginx,如果再次启动该命令就会提示端口冲突,所以需要先关闭再启动

ps -ef | grep -i "nginx" # 查找 nginx 服务

nginx -s stop # 停止 nginx 进程
# -s 作用是给 nginx 发送某种信号
# stop 立刻停止服务;
# quit 优雅的停止服务;
# reload 平滑重启,可以在不重启 Nginx 的情况下重载配置文件;
# reopen 重新开始记录日志文件

nginx -t # 检查 nginx 的配置文件语法是否有误

配置文件

配置文件的语法

nginx.conf 是由指令和指令块组成的

  • 每行语句都使用分号结尾,指令和参数之间使用空格分隔
  • 每个指令块使用 {} 组织
  • 使用 # 表示注释符
  • 使用 $变量名 来创建一个变量
  • Nginx 可以使用 include 组合多个配置文件

其核心功能都在 http{} 指令块里,http{} 指令块里面还能包括下面的几种指令块

  • server{}:对应一个站点配置,反向代理,静态资源站点
  • location{}:通过正则表达式拦截 URL,然后对这个请求进行相应操作
  • upstream{}:定义负载均衡池

自带的全局参数

  1. $remote_addr$http_x_forwarded_for 用以记录客户端的 ip 地址;
  2. $remote_user :用来记录客户端用户名称;
  3. $time_local : 用来记录访问时间与时区;
  4. $request : 用来记录请求的 url 与 http 协议;
  5. $status : 用来记录请求状态;成功是200;
  6. $body_bytes_sent :记录发送给客户端文件主体内容大小;
  7. $http_referer :用来记录从那个页面链接访问过来的;
  8. $http_user_agent :记录客户端浏览器的相关信息;
  9. $scheme:协议头

使用例

if ($scheme = https) {
rewrite ^(.*)? http://$http_host$1 permanent;
}

配置文件模板

配置文件的各个部分的作用直接写在注释里了

# 这部分是全局指令
# 配置影响 Nginx 全局的指令。
# 一般有运行 Nginx 服务器的用户组,Nginx 进程 pid 存放路径,日志存放路径,配置文件引入,允许生成 worker process 数等。

user www-data; # 定义 Nginx 运行的用户和用户组
worker_processes auto; # Nginx 进程数,最好不要超过 CPU 总核心数

# 这个 pid 文件就是用来记录 Nginx 的进程 ID 的
# 在 Linux/Unix下,很多程序比如 Nginx 会启动多个进程,而发信号的时候需要知道要向哪个进程发信号。
# 不同的进程有不同的pid(process id)
pid /run/nginx.pid;
# 实际上 nginx 和 maven 一样,配置文件一般都是模块化的,以下引入三个目录下的文件
include /etc/nginx/modules-enabled/*.conf;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
include /etc/nginx/mime.types; # 文件扩展名与文件类型映射表



# events块
# 配置影响 Nginx 服务器或与用户的网络连接。
# 有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
events {
# 写在花括号里的是局部指令
# 惊群现象:一个网路连接到来,多个睡眠的进程被同时叫醒,但只有一个进程能获得链接,这样会影响系统性能。
accept_mutex on; # 设置网路连接序列化,防止惊群现象发生,默认为on
multi_accept on; # 设置一个进程是否同时接受多个网络连接,默认为off
#use epoll; # 事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
worker_connections 1024; # 最大连接数,默认为512
}


# http 语句块,核心功能的配置
# 可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。
# 如文件引入,mime-type 定义,日志自定义,是否使用 sendfile 传输文件,连接超时时间,单连接请求数等。
http {

default_type application/octet-stream; # 默认文件类型,默认为text/plain
error_page 404 https://www.baidu.com; # 错误页

##################
# Basic Settings #
##################

# 允许 sendfile 方式传输文件,默认为 off,可以在 http 块,server 块,location 块配置
sendfile on;
sendfile_max_chunk 100k; # 每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65; # 连接超时时间,默认为75s,可以在http,server,location块。
types_hash_max_size 2048;
# server_tokens off;

#################
# Gzip Settings #
#################

gzip on; # 开启 gzip 压缩
gzip_min_length 1k; # 最小压缩文件大小
gzip_buffers 4 16k; # 压缩缓冲区
gzip_http_version 1.0; # 压缩版本(默认 1.1,前端如果是 squid2.5 请使用 1.0)
gzip_comp_level 2; # 压缩等级
gzip_types text/plain application/javascript text/css text/xml;
gzip_vary on;


################
# SSL Settings #
################

ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;

####################
# Logging Settings #
####################

# 自定义格式 注:combined 为日志格式的默认值
log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for';
# access_log /var/log/nginx/access.log; # 访问日志
access_log /var/log/nginx/access.log myFormat; # 使用自定义的日志格式
# access_log off; #取消服务日志

# 制定日志路径,级别。
error_log /var/log/nginx/error.log; # 错误日志:存放路径。
# 这个设置可以放入全局块,http块,server块
# 级别以此为:debug|info|notice|warn|error|crit|alert|emerg
#
# 例如为每种级别的日志放在不同的位置
# error_log /var/log/nginx/notice/error.log notice;
# error_log /var/log/nginx/info/error.log info;
# error_log /var/log/nginx/info/error.log debug;


# 这个 server 就是虚拟主机
server{
listen 8091; # 修改监听端口
# listen [::]:8091 default_server; # 或者以这种形式
server_name 127.0.0.1; # 监听地址(可以直接写域名)
keepalive_requests 120; # 单连接请求上限次数。

# location 块
# 配置请求的路由,以及各种页面的处理情况。
location ~*^.+$ { # 请求的 url 过滤,正则匹配,~ 为区分大小写,~* 为不区分大小写。
root /web/test/index; # 项目路径
index index.html; # 设置默认页
# proxy_pass http://localhost:7758; # 访问的请求映射到这里(配置反向代理)
deny 172.18.5.54; # 拒绝的 ip
allow 127.0.0.1; # 允许的 ip
}

# 可以配置多个 location 块
# 这里配置图片缓存时间
location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$ {
expires 10d;
}

# 同理设置 JS 和 CSS 缓存时间
location ~ .*.(js|css)$ {
expires 1h;
}
}
}

Nginx 支持的文件类型

/etc/nginx 目录下的 mime.types 文件里面记录了 Nginx 支持的文件类型

types {
text/html html htm shtml;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
application/javascript js;
application/atom+xml atom;
application/rss+xml rss;

text/mathml mml;
text/plain txt;
text/vnd.sun.j2me.app-descriptor jad;
text/vnd.wap.wml wml;
text/x-component htc;

image/png png;
image/tiff tif tiff;
image/vnd.wap.wbmp wbmp;
image/x-icon ico;
image/x-jng jng;
image/x-ms-bmp bmp;
image/svg+xml svg svgz;
image/webp webp;

application/font-woff woff;
application/java-archive jar war ear;
application/json json;
application/mac-binhex40 hqx;
application/msword doc;
application/pdf pdf;
application/postscript ps eps ai;
application/rtf rtf;
application/vnd.apple.mpegurl m3u8;
application/vnd.ms-excel xls;
application/vnd.ms-fontobject eot;
application/vnd.ms-powerpoint ppt;
application/vnd.wap.wmlc wmlc;
application/vnd.google-earth.kml+xml kml;
application/vnd.google-earth.kmz kmz;
application/x-7z-compressed 7z;
application/x-cocoa cco;
application/x-java-archive-diff jardiff;
application/x-java-jnlp-file jnlp;
application/x-makeself run;
application/x-perl pl pm;
application/x-pilot prc pdb;
application/x-rar-compressed rar;
application/x-redhat-package-manager rpm;
application/x-sea sea;
application/x-shockwave-flash swf;
application/x-stuffit sit;
application/x-tcl tcl tk;
application/x-x509-ca-cert der pem crt;
application/x-xpinstall xpi;
application/xhtml+xml xhtml;
application/xspf+xml xspf;
application/zip zip;

application/octet-stream bin exe dll;
application/octet-stream deb;
application/octet-stream dmg;
application/octet-stream iso img;
application/octet-stream msi msp msm;

application/vnd.openxmlformats-officedocument.wordprocessingml.document docx;
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx;
application/vnd.openxmlformats-officedocument.presentationml.presentation pptx;

audio/midi mid midi kar;
audio/mpeg mp3;
audio/ogg ogg;
audio/x-m4a m4a;
audio/x-realaudio ra;

video/3gpp 3gpp 3gp;
video/mp2t ts;
video/mp4 mp4;
video/mpeg mpeg mpg;
video/quicktime mov;
video/webm webm;
video/x-flv flv;
video/x-m4v m4v;
video/x-mng mng;
video/x-ms-asf asx asf;
video/x-ms-wmv wmv;
video/x-msvideo avi;
}

配置负载均衡

参考资料 Nginx 反向代理与负载均衡详解

Nginx 支持很多种负载均衡策略,比较重点的如下:

  • round robin(轮询)
  • random(随机)
  • weight(权重)
  • fair(按响应时长,三方插件)
  • url_hash(url 的 hash 值)
  • ip_hash(ip 的 hash 值)
  • least_conn(最少连接数)

轮询策略

写一组被代理的服务器地址,然后配置负载均衡的算法

# 默认配置就是轮询策略
# 服务器处理请求的顺序:ABABABABAB...
upstream mysvr {
server 192.168.10.121:3333;
server 192.168.10.122:3333;
}
# server 这部分下面都是一样的,就省略不写了
server {
....
location ~*^.+$ {
proxy_pass http://mysvr; # 请求转向 mysvr 定义的服务器列表
}
}

热备策略

如果有2台服务器,当一台服务器发生事故时,才启用第二台服务器给提供服务。

upstream mysvr { 
server 127.0.0.1:7878;
server 192.168.10.121:3333 backup; #热备
}

加权轮询策略

跟据配置的权重的大小而分发给不同服务器不同数量的请求。

如果不设置,则默认为1。下面服务器的请求顺序为:ABBABBABBABBABB....

upstream mysvr { 
server 127.0.0.1:7878 weight=1;
server 192.168.10.121:3333 weight=2;
}

ip_hash 策略

Nginx 会让相同的客户端 ip 请求相同的服务器。

upstream mysvr { 
server 127.0.0.1:7878;
server 192.168.10.121:3333;
ip_hash;
}

自定义策略

nginx 负载均衡配置的内置了几个状态参数

  • down:表示当前的 server 暂时不参与负载均衡。
  • backup:预留的备份机器。当其他所有的非 backup 机器出现故障或者忙的时候,才会请求 backup 机器,因此这台机器的压力最轻。
  • max_fails:允许请求失败的次数,默认为1。当超过最大次数时,返回 proxy_next_upstream 模块定义的错误。
  • fail_timeout:在经历了 max_fails 次失败后,暂停服务的时间。max_fails 可以和 fail_timeout 一起使用。
upstream mysvr { 
server 127.0.0.1:7878 weight=2 max_fails=2 fail_timeout=2;
server 192.168.10.121:3333 weight=1 max_fails=2 fail_timeout=1;
}

Nginx 虚拟主机

虚拟主机指的就是一个独立的站点配置,它能够拥有自己独立的域名、独立的 IP、独立的端口配置,能配置完整的 www 服务,例如网站搭建,ftp 服务搭建、邮件服务器、代理等等

一个 http 代码块里面可以写多个 server

Server 的配置

# 这个 server 就是虚拟主机
server{
listen 8091; # 修改监听端口
# listen [::]:8091 default_server; # 或者以这种形式
server_name 127.0.0.1; # 监听地址(可以直接写域名)
keepalive_requests 120; # 单连接请求上限次数。
charset utf-8; # 设置网站的编码
# 自定义格式 注:combined 为日志格式的默认值
log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for';
# access_log /var/log/nginx/access.log; # 访问日志
access_log /var/log/nginx/access.log myFormat; # 使用自定义的日志格式
# access_log off; #取消服务日志

# 制定日志路径,级别。
error_log /var/log/nginx/error.log; # 错误日志:存放路径。

# location 块
# 配置请求的路由,以及各种页面的处理情况。
location ~*^.+$ { # 请求的 url 过滤,正则匹配,~ 为区分大小写,~* 为不区分大小写。
root /web/test/index; # 项目路径
index index.html; # 设置默认页
# proxy_pass http://localhost:7758; # 访问的请求映射到这里(配置反向代理)
deny 172.18.5.54; # 拒绝的 ip
allow 127.0.0.1; # 允许的 ip
}

# 可以配置多个 location 块
# 这里配置图片缓存时间
location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$ {
expires 10d;
}

# 同理设置 JS 和 CSS 缓存时间
location ~ .*.(js|css)$ {
expires 1h;
}
}

location 后面跟着一个 URI 匹配规则,匹配到的 URI 会执行 location 代码块里面的配置

配置 Gzip 压缩

#################
# Gzip Settings #
#################

gzip on; # 开启 gzip 压缩
gzip_min_length 1k; # 最小压缩文件大小
gzip_buffers 4 16k; # 压缩缓冲区
gzip_http_version 1.0; # 压缩版本(默认 1.1,前端如果是 squid2.5 请使用 1.0)
gzip_comp_level 2; # 压缩等级,等级越低压缩等级越高,所以对计算机 CPU 消耗越高
gzip_types application/javascript text/plain application/x-javascript text/css application/xml text/javascript;
# gzip_types 其他类型也可以参考上面的 “支持的文件类型”
gzip_vary on;

还有几个比较复杂的配置

1、gzip_vary 告诉接收方发送的数据经过了压缩处理,开启后的效果是在响应头部添加了 Accept-Encoding:gzip,这对于本身不支持 gzip 压缩的客户端浏览器有用。

2、gzip_proxied:Nginx 做为反向代理的时候启用,前提是后端服务器返回的响应页头部中,Requests 部分包含用于通知代理服务器的 Via 头域。

gzip_proxied off|expired|no-cache|no-sotre|private|no_last_modified|no_etag|auth|any]
#eg: gzip_proxied any
# off – 关闭所有的代理结果数据压缩
# expired – 启用压缩,如果header中包含”Expires”头信息
# no-cache – 启用压缩,如果header中包含”Cache-Control:no-cache”头信息
# no-store – 启用压缩,如果header中包含”Cache-Control:no-store”头信息
# private – 启用压缩,如果header中包含”Cache-Control:private”头信息
# no_last_modified – 启用压缩,如果header中包含”Last_Modified”头信息
# no_etag – 启用压缩,如果header中包含“ETag”头信息
# auth – 启用压缩,如果header中包含“Authorization”头信息
# any – 无条件压缩所有结果数据

3、gzip_disable:对于不同类型客户端发起的请求,可选择性开启或者关闭 gzip 功能。

gzip_disable regex ...;
# eg: gzip_disable MSIE [4-6]\.

location 匹配

语法规则

location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }

修饰符

  • = 表示精确匹配。只有请求的 url 路径与后面的字符串完全相等时,才会命中。
  • ~ 表示该规则是使用正则定义的,区分大小写。
  • ~* 表示该规则是使用正则定义的,不区分大小写。
  • ^~ 表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找。

示例文件

location = / {
[ configuration A ]
}

location / {
[ configuration B ]
}

location /user/ {
[ configuration C ]
}

location ^~ /images/ {
[ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
[ configuration E ]
}

日志系统

参考资料 超详细!Nginx 日志配置实践

####################
# Logging Settings #
####################
# 自定义格式 注:combined 为日志格式的默认值
log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent$http_referer $http_user_agent $http_x_forwarded_for';
# access_log /var/log/nginx/access.log; # 访问日志
access_log /var/log/nginx/access.log myFormat; # 使用自定义的日志格式
# access_log off; #取消服务日志

# 制定日志路径,级别。
error_log /var/log/nginx/error.log; # 错误日志:存放路径。
# 这个设置可以放入全局块,http块,server块
# 级别以此为:debug|info|notice|warn|error|crit|alert|emerg
#
# 例如为每种级别的日志放在不同的位置
error_log /var/log/nginx/notice/error.log notice;
error_log /var/log/nginx/info/error.log info;
error_log /var/log/nginx/info/error.log debug;

Nginx 日志主要分为两种:access_log(访问日志) 和 error_log(错误日志)。

通过访问日志我们可以得到用户的 IP 地址、浏览器的信息,请求的处理时间等信息。错误日志记录了访问出错的信息,可以帮助我们定位错误的原因。

监控日志文件

# 显示文件大小
du -h ./*
# 显示文件 -n 表示显示行号
cat filename.txt -n
# 监控一个文件
tail -f access.log

访客日志

访问日志主要记录客户端的请求。客户端向 Nginx 服务器发起的每一次请求都记录在这里。客户端 IP,浏览器信息,referer,请求处理时间,请求 URL 等都可以在访问日志中得到。当然具体要记录哪些信息,可以通过 log_format 指令定义。

# 语法
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
  • path 指定日志的存放位置。
  • format 指定日志的格式。默认使用预定义的 combined
  • buffer 用来指定日志写入时的缓存大小。默认是 64k。
  • gzip 日志写入前先进行压缩。压缩率可以指定,从 1 到 9 数值越大压缩比越高,同时压缩的速度也越慢。默认是 1。
  • flush 设置缓存的有效时间。如果超过 flush 指定的时间,缓存中的内容将被清空。
  • if 条件判断。如果指定的条件计算为 0 或空字符串,那么该请求不会写入日志。

可以应用 access_log 指令的作用域分别有 http,server,location,limit_except。

# 示例
access_log /var/logs/nginx-access.log buffer=32k gzip flush=1m

使用 log_format 自定义日志格式

# combined 日志格式
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';

下面是 log_format 指令中常用的一些变量:

$bytes_sent
发送给客户端的总字节数

$body_bytes_sent
发送给客户端的字节数,不包括响应头的大小

$connection
连接序列号

$connection_requests
当前通过连接发出的请求数量

$msec
日志写入时间,单位为秒,精度是毫秒

$pipe
如果请求是通过http流水线发送,则其值为"p",否则为“."

$request_length
求长度(包括请求行,请求头和请求体)

$request_time
请求处理时长,单位为秒,精度为毫秒,从读入客户端的第一个字节开始,直到把最后一个字符发送张客户端进行日志写入为止

$status
响应状态码

$time_iso8601
标准格式的本地时间,形如“2017-05-24T18:31:27+08:00”

$time_local
通用日志格式下的本地时间,如"24/May/2017:18:31:27 +0800"

$http_referer
请求的referer地址。

$http_user_agent
客户端浏览器信息。

$remote_addr
客户端IP

$http_x_forwarded_for
当前端有代理服务器时,设置web节点记录客户端地址的配置,此参数生效的前提是代理服务器也要进行相关的x_forwarded_for设置。

$request
完整的原始请求行,如 "GET / HTTP/1.1"

$remote_user
客户端用户名称,针对启用了用户认证的请求

$request_uri
完整的请求地址,如 "https://daojia.com/"

错误日志

配置错误日志文件的路径和日志级别。

error_log file [level];
Default:
error_log logs/error.log error;
# 按紧急程度从低到高排列
# level可以是 debug, info, notice, warn, error, crit, alert,emerg 中的任意值

代理 WebSocket

map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

# 配置远程 VsCode
server
{
listen 80;
server_name code.alsritter.icu;
location / {
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:7758;
}
}

HTTPS to HTTP

如果直接将 HTTPS 里面的内容删掉并跳转 HTTP 是不行的,需要加个 if 判断才行

server
{
# 配置HTTPS的默认访问端口号为443。此处如果未配置HTTPS的默认访问端口,可能会造成Nginx无法启动。Nginx 1.15.0以上版本请使用listen 443 ssl代替listen 443和ssl on。
listen 443;
# 监听的域名
server_name alsritter.icu www.alsritter.icu;
# ..省略 SSL 的配置
# 将所有HTTPS请求通过rewrite重定向到HTTP。这里必须加个 if
location / {
if ($scheme = https) {
rewrite ^(.*)? http://$http_host$1 permanent;
}
}
}

TODO: 待更新...